package com.ego.user.service;

import com.ego.auth.entity.UserInfo;
import com.ego.auth.utils.JwtUtils;
import com.ego.common.utils.PageResult;
import com.ego.user.utils.CodecUtils;
import com.ego.common.utils.GenerateCodeUtils;
import com.ego.user.mapper.UserMapper;
import com.ego.user.pojo.User;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@Transactional
public class UserService {

    @Resource
    private UserMapper userMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    public Boolean checkUserData(String data, Integer type) {
        User user = new User();
        if (type == 1) {
            user.setUsername(data);
        }
        if (type == 2) {
            user.setUsername(data);
        }
        int count = userMapper.selectCount(user);
        return count > 0 ? false : true;
    }

    public Boolean send(String phone) {
        Map<String, String> map = new HashMap<>();
        try {
            map.put("phone", phone);
            String code = GenerateCodeUtils.generateCode(6);
            map.put("code", code);
            //存放到redis中
            stringRedisTemplate.opsForValue().set("ego:code" + phone, code, 5, TimeUnit.MINUTES);
            //发送到消息队列
            this.amqpTemplate.convertAndSend("sms.verify.code", map);
            return true;
        } catch (Exception e) {
            throw new RuntimeException("phone:" + phone + "发送验证码失败..");
        }

    }

    public void register(User user, String code) throws Exception {
        //校验传过来的user参数,虽然前端校验过了,但是就怕绕过前端校验的,比如用postman骚操作的
        // 引入hibernate提供的相关的依赖,然后在实体类上加上相关注解
        String key = "ego:code" + user.getPhone().trim();
        //从redis中取出验证码
        String redisCode = this.stringRedisTemplate.opsForValue().get(key);
        if (!redisCode.equals(code)) {
            return;
        }
        user.setCreated(new Date());
        user.setUsername(user.getUsername().trim());
        user.setPassword(user.getPassword().trim());
        //加密规则,对用户名和密码拼接的字符串进行加密
        //user.setPassword(passwordEncoder.encode(user.getUsername().trim() + user.getPassword().trim()));
        user.setPassword(CodecUtils.passwordBcryptEncode(user.getUsername(), user.getPassword()
        ));
        //来保存用户
        int i = this.userMapper.insertSelective(user);
        if (i == 1) {//确保插入数据库成功
            //删除redis中的验证码
            try {
                stringRedisTemplate.delete(key);
            } catch (Exception e) {
                throw new Exception("删除验证码缓存失败");
            }
        }

    }

    public User queryUser(String username, String password) {
        User record = new User();
        record.setUsername(username);
        User user = this.userMapper.selectOne(record);
        // 校验用户名
        if (user == null) {
            return null;
        }
        // 校验密码
        if (!CodecUtils.passwordConfirm(username + password, user.getPassword())) {
            return null;
        }
        // 用户名密码都正确
        return user;
    }


    public User getUserByUserInfo(UserInfo userInfo) {
        return this.userMapper.selectByPrimaryKey(userInfo.getId());
    }

    public PageResult<User> getPageResult(Integer pageNo, Integer pageSize, String sortBy, Boolean descending, String key) {

        PageHelper.startPage(pageNo, pageSize);

        Example example = new Example(User.class);
        if (StringUtils.isNotBlank(key)) {
            example.createCriteria().andLike("username", "%" + key + "%").orLike("phone", key);
        }
        if (StringUtils.isNotBlank(sortBy)) {
            example.setOrderByClause(sortBy + " " + (descending ? "desc" : "asc"));
        }
        List<User> list = userMapper.selectByExample(example);
        PageInfo<User> pageInfo = new PageInfo<>(list);
        PageResult<User> pageResult = new PageResult<>();
        pageResult.setItems(pageInfo.getList());
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setTotalPage(Long.valueOf(pageInfo.getPages()));
        return pageResult;
    }
}
